package com.yehun.web.controller;

import com.yehun.model.UserLoginModel;
import com.yehun.shiro.ShiroUser;
import com.yehun.shiro.ShiroUserType;
import com.yehun.shiro.UserToken;
import com.yehun.shiro.UsernamePasswordTypeToken;
import com.yehun.utils.MD5Utils;
import com.yehun.utils.RequestUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.Valid;

@Controller
@RequestMapping(value = "user")
public class UserController extends BaseController {

    private final static Logger logger = LoggerFactory.getLogger(UserController.class);

    @RequestMapping(value = "login", method = RequestMethod.GET)
    public String login(Model model) {
        Subject subject = SecurityUtils.getSubject();
        logger.info("principal={}", subject.getPrincipal());
        if (subject.isAuthenticated()) {
            return "redirect:info";
        }
        model.addAttribute("userLogin", new UserLoginModel());
        return "user/login";
    }

    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ModelAndView login(@Valid @ModelAttribute("userLogin") UserLoginModel userLogin, BindingResult bindingResult) {
        ModelAndView view = new ModelAndView("user/login");
        logger.info("UserController.loginPost, userLogin={}", userLogin.toString());
        if (!bindingResult.hasErrors()) {
            logger.info("UserController.login, userLogin valid success");
            Subject subject = SecurityUtils.getSubject();
            UserToken token = new UserToken(userLogin.getUsername(), MD5Utils.md5(userLogin.getPassword()));
            token.setType(ShiroUserType.USER);
            token.setRememberMe(true);
            token.setHost(RequestUtils.getIp());
            try {
                subject.login(token);
            } catch (UnknownAccountException e) {
                logger.debug("账号不存在：{}", e);
                view.addObject("message", "账号不存在");
            } catch (DisabledAccountException e) {
                logger.debug("账号未启用：{}", e);
                view.addObject("message", "账号未启用");
            } catch (IncorrectCredentialsException e) {
                e.printStackTrace();
                logger.debug("密码错误：{}", e);
                view.addObject("message", "密码错误");
            } catch (RuntimeException e) {
                logger.error("未知错误,请联系管理员：{}", e);
                view.addObject("message", "未知错误,请联系管理员");
            }
            if (subject.isAuthenticated()) {
                view.setViewName("redirect:info");
                return view;
            }
        }
        return view;
    }

    @RequestMapping(value = "logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            subject.logout();
        }
        return "redirect:login";
    }

    @RequestMapping(value = "info")
    public String info() {
        ShiroUser currentUser = this.getCurrentUser();
        logger.info("UserController.info, currentUser={}", currentUser.toString());
        return "user/info";
    }

    @ResponseBody
    @RequestMapping(value = "unauth")
    public String unauth() {
        ShiroUser user = this.getCurrentUser();
        return user.getName() + " no permission";
    }

    @ResponseBody
    @RequestMapping(value = "updateInfo")
    public String updateInfo() { return "updateInfo"; }

    @ResponseBody
    @RequestMapping(value = "updatePassword")
    public String updatePassword() { return "updatePassword"; }


}
